<?PHP

namespace Lib;

define('IS_AJAX', ((isset($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest')) ? true : false);

// 设置时区
if (!ini_get('date.timezone')) {
    date_default_timezone_set('PRC');
}

// 显示错误。
ini_set('display_errors', 'on');

// 报告所有错误
error_reporting(E_ALL);

/**
 * 路由
 * @package SDF\Core
 */
class Route {
    /**
     * @throws \Exception
     */
    public static function route_start() {
        $parse = parse_url($_SERVER['REQUEST_URI']);
        //todo 优先从路由匹配中获取class与action
        $pathinfo = pathinfo($parse['path']);
        $class = str_replace('/', '\\', $pathinfo['dirname']);
        $action = $pathinfo['filename'];//($path);

        if (empty($action)){
            $action = 'home';
        }

        if ($class == '\\'){
            $class = '\\'.$action;
            $action = 'index';
        }

        if(!defined('__CONTROLLER__')){
            define('__CONTROLLER__',$class);//__CONTROLLER__（__或者__URL__ 兼容考虑）： 前控制器的URL地址（不含域名）
        }
        if(!defined('__URL__')){
            define('__URL__',str_replace('\\','/',$class));
        }
        if(!defined('__ACTION__')){//__ACTION__：当前操作的URL地址 （不含域名）
            define('__ACTION__',__URL__.'/'.$action);
        }
        /*echo __CONTROLLER__;echo PHP_EOL;
        echo __URL__;echo PHP_EOL;
        echo __ACTION__;exit;*/

        try{
            $ret = self::run($class,$action);
            if ($ret === NULL) {
                exit;
            }
            if (is_string($ret)){
                echo $ret;
            }elseif(is_array($ret)){
                self::setHeaderContentType('JSON');
                echo \json_encode($ret);
            }else{
                echo $ret;
            }

        }catch (\Exception $e){
            self::setHeaderTtatus($e->getCode());
            echo $e->getCode().' '.$e->getMessage();
            Logs::Error($e->getCode().' '.$e->getMessage());
        }

    }

    /**
     * 实例化某个类，并运行指定方法
     * @param $class
     * @param $action
     * @return mixed
     * @throws \Exception
     */
    public static function run($class,$action){
        $class = 'App\\Controllers'.$class;
        if (!\class_exists($class)) {
            throw new \Exception("no class {$class}",404);
        }

        $object = new $class();

        if (!method_exists($object, $action)) {
            throw new \Exception('找不到方法：' . $class . '->' . $action . '()',404);
        }

        return call_user_func_array(array($object, $action),[]); //调用对象里的方法并传参
    }

    /**
     * 设置HTTP状态码
     * @param int $code
     * @param string $text
     */
    public static function setHeaderTtatus($code = 200, $text = ''){
        $static = array(
            200	=> 'OK',
            201	=> 'Created',
            202	=> 'Accepted',
            203	=> 'Non-Authoritative Information',
            204	=> 'No Content',
            205	=> 'Reset Content',
            206	=> 'Partial Content',

            300	=> 'Multiple Choices',
            301	=> 'Moved Permanently',
            302	=> 'Found',
            304	=> 'Not Modified',
            305	=> 'Use Proxy',
            307	=> 'Temporary Redirect',

            400	=> 'Bad Request',
            401	=> 'Unauthorized',
            403	=> 'Forbidden',
            404	=> 'Not Found',
            405	=> 'Method Not Allowed',
            406	=> 'Not Acceptable',
            407	=> 'Proxy Authentication Required',
            408	=> 'Request Timeout',
            409	=> 'Conflict',
            410	=> 'Gone',
            411	=> 'Length Required',
            412	=> 'Precondition Failed',
            413	=> 'Request Entity Too Large',
            414	=> 'Request-URI Too Long',
            415	=> 'Unsupported Media Type',
            416	=> 'Requested Range Not Satisfiable',
            417	=> 'Expectation Failed',

            500	=> 'Internal Server Error',
            501	=> 'Not Implemented',
            502	=> 'Bad Gateway',
            503	=> 'Service Unavailable',
            504	=> 'Gateway Timeout',
            505	=> 'HTTP Version Not Supported'
        );
        if ($code == '' OR ! is_int($code)){
            $code = 500;
        }
        if (isset($static[$code]) AND $text == ''){
            $text = $static[$code];
        }
        if ($text == ''){
            $text = 'No status text available.  Please check your status code number or supply your own message text.';
        }
        $server_protocol = (isset($_SERVER['SERVER_PROTOCOL'])) ? $_SERVER['SERVER_PROTOCOL'] : FALSE;
        if (substr(php_sapi_name(), 0, 3) == 'cgi'){
            \header("Status: {$code} {$text}", TRUE);
        }elseif ($server_protocol == 'HTTP/1.1' OR $server_protocol == 'HTTP/1.0'){
            \header($server_protocol." {$code} {$text}", TRUE, $code);
        }else{
            \header("HTTP/1.1 {$code} {$text}", TRUE, $code);
        }
    }

    /**
     * 设置HTTP Content-Type
     * @param string $type
     */
    public static function setHeaderContentType($type='JSON'){
        $type = strtoupper($type);
        $data = [
            'HTML'=>'Content-Type:text/html;charset=utf-8',
            'JSON'=>'application/json',
            'ATOM'=>'application/atom+xml',
            'CSS'=>'text/css',
            'JAVASCRIPT'=>'text/javascript',
            'JPEG'=>'image/jpeg',
            'PDF'=>'application/pdf',
            'RSS'=>'application/rss+xml; charset=ISO-8859-1',
            'TEXT/PLAIN'=>'text/plain',
            'XML'=>'text/xml',
        ];
        if (empty($data[$type])){
            $value = $data['HTML'];
        }else{
            $value =$data[$type];
        }
        \header("Content-Type: {$value}");
    }

    /**
     * 添加路由规则
     * @param $methods
     * @param $uri
     * @param $action
     */
    public static function addRoute($methods,$uri,$action){
        /*if (is_string($action)) {
            $action = ['uses' => $action, 'controller' => $action];
        } elseif ($action instanceof Closure) {
            $action = [$action];
        }*/
    }
}